/**
 * Copyright ®2010 GuoHuaLife Co. Ltd. All rights reserved. Package: com.ebiz.platform.common.api.util FileName:
 * SftpUtil.java
 */
package com.han.utils;

import com.jcraft.jsch.*;
import com.jcraft.jsch.ChannelSftp.LsEntry;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.Vector;

/**
 * Sftp调用工具类
 * 
 * @date 2010-11-20
 * @since JDK 1.5
 * @author dingkui
 * @version 1.0
 * 
 */
@Slf4j
public class SftpUtil {

    /**
     * jcraft的ChannelSftp类实例，信息传输通道
     */
    private ChannelSftp channelSftp;

    private ChannelExec channelExec;
    
    /**
     * jcraft的session类实例，用来持久化连接
     */
    private Session session;

    /**
     * 当前操作路径
     */
    private String currentPath;
    
    /**
     * 默认编码
     * ISR-33升级JSCH版本为0.1.50，此版本链接SFTP编码必须为UTF-8
     */
    private static final String DEFAULT_ENCODE = "UTF-8";
    
    public String getCurrentPath(){
    	return this.currentPath;
    }

    /**
     * 当前目录下文件列表
     */
    private Vector currentFiles;


    /**
     * 取得当前的ChannelSftp实例
     * 
     * @return 当前的ChannelSftp实例
     */
    public ChannelSftp getChannelSftp() {
        return channelSftp;
    }

    /**
     * 根据指定config相关信息，连接远程sftp服务器
     * 
     * @param ftpConfig
     *            ftp服务配置信息类
     */
    public void connectServer(FtpConfig ftpConfig) {
        log.info("[链接SFTP][开始]");
        long start = System.currentTimeMillis();
        String server = ftpConfig.getServer();
        int port = ftpConfig.getPort();
        String username = ftpConfig.getUsername();
        String password = ftpConfig.getPassword();
        String location = "/";
        if (null != ftpConfig.getLocation() && !"".equals(ftpConfig.getLocation())) {
            location = ftpConfig.getLocation();
        }
        String encode = ftpConfig.getEncode();
        connectServer(server, port, username, password, location, encode);
        log.info("[链接SFTP][结束][耗时：" + (System.currentTimeMillis() - start) +"]");
    }

    /**
     * 链接远程ftp服务器
     * 
     * @param server
     *            服务器地址
     * @param port
     *            服务器端口
     * @param user
     *            用户名
     * @param password
     *            密码
     * @param path
     *            登陆后的默认路径
     * @param encode
     *            服务器文件系统编码
     */
    public void connectServer(String server, int port, String user, String password, String path, String encode) {
        String errorMsg = "";
        try {
            JSch jsch = new JSch();
            session = jsch.getSession(user, server, port);
            session.setPassword(password);
            // session.setUserInfo(new SftpUserInfo(ftpPassword));
            Properties sshConfig = new Properties();
            sshConfig.put("StrictHostKeyChecking", "no");
            session.setConfig(sshConfig);
            session.connect();
            channelSftp = (ChannelSftp) session.openChannel("sftp");
            channelSftp.connect();
            // ISR-33 修改默认编码格式为UTF-8
            String encode1 = DEFAULT_ENCODE;
            channelSftp.setFilenameEncoding(encode1);
            currentPath=channelSftp.getHome();

        }
        catch (SftpException e) {
            errorMsg = "无法使用SFTP传输文件!";
            e.printStackTrace();
            throw new RuntimeException(errorMsg);
        }
        catch (JSchException e) {
            errorMsg = "没有权限与SFTP服务器连接!";
            throw new RuntimeException(errorMsg);
        }
    }

    /**
     * 内部方法，关闭OutputStream
     * 
     * @param os
     *            希望关闭的OutputStream
     */
    private void closeOutputStream(OutputStream os) {
        try {
            if (null != os) {
                os.close();
            }
        }
        catch (IOException e) {
            throw new RuntimeException("关闭OutputStream时出现异常：" + e.getMessage());
        }
    }

    /**
     * 内部方法，关闭InputStream
     * 
     * @param is
     *            希望关闭的InputStream
     */
    private void closeInputStream(InputStream is) {
        try {
            if (null != is) {
                is.close();
            }
        }
        catch (IOException e) {
            throw new RuntimeException("关闭OutputStream时出现异常：" + e.getMessage());
        }
    }

    /**
     * 内部方法，取得当前操作目录下的全部文件列表
     */
    private void getCurrentFileList() {
        try {
            Vector v = channelSftp.ls(currentPath);
            this.currentFiles = v;
        }
        catch (SftpException e) {
            log.error("错误信息"+e);

        }
    }

    /**
     * 内部方法，获得操作路径
     * 
     * @param path
     *      参数
     * @return String
     */
    private String getOperationPath(String path) {
        String operactePath;
        if (!"".equals(path.trim())&&'/' == path.charAt(0)) {
            operactePath = path;
        }
        else {
            operactePath = currentPath + path;
        }
        if (operactePath.lastIndexOf("/") != operactePath.length() - 1) {
            operactePath = operactePath + "/";
        }
        return operactePath;
    }

    /**
     * 内部方法，获得操作路径
     * 
     * @param path
     *      参数
     * @return String
     */
    private String getFileOperationPath(String path) {
        String operactePath;
        if ('/' == path.charAt(0)) {
            operactePath = path;
        }
        else {
            operactePath = currentPath + "/" + path;
        }
        return operactePath;
    }

    /**
     * 内部方法，验证路径和sftp连接
     * 
     * @param path
     *            路径
     * @return 验证结果
     */
    private boolean dirValidation(String path) {
        boolean result = true;
        if (channelSftp == null || !channelSftp.isConnected()) {
            result = false;

            log.error("操作出现异常：channelSftp连接未创建");
        }
        if (null != path && "".equals(path)) {
            result = false;

            log.error("操作出现异常：指定的path不能为空");
        }
        return result;
    }

    /**
     * 内部方法，判断一个字符串，是文件路径
     * 
     * @param path
     *            路径字符串
     * @return 判断结果，是返回ture，否则false
     */
    private boolean isFilePath(String path) {
        boolean result = false;
        //if (null != path && !"".equals(path) && path.lastIndexOf("/") < path.length()) {
        if (null != path && !"".equals(path) && !path.endsWith("/")) {
            result = true;
        }
        return result;
    }

    /**
     * 变换当前目录
     * 
     * @param path
     *            希望进入的目录
     * @return 成功为true，失败返回false
     */
    public boolean changeDir(String path) {
        boolean result = false;
        if (dirValidation(path)) {
            String testPath = getOperationPath(path);
            try {
                channelSftp.cd(testPath);
                this.currentPath = testPath;
                result = true;
            }
            catch (SftpException e) {
                throw new RuntimeException("变换目录'" + path + "'时发生错误：" + e.getMessage());
            }
        }
        return result;
    }

    /**
     * 创建目录
     * 
     * @param remotePath
     *            远程目录
     * @return 操作结果，成功为true，失败为false
     */
    public boolean makeDir(String remotePath) {
        boolean result = false;
        if (dirValidation(remotePath)) {
            String testPath = getOperationPath(remotePath);
            try {
                channelSftp.mkdir(testPath);
                result = true;
            }
            catch (SftpException e) {
                throw new RuntimeException("创建目录'" + remotePath + "'时发生错误：" + e.getMessage());
            }
        }
        return result;
    }

	/**
	 * 创建多级路径
	 * 
	 * @param remotePath
	 *            传入的路径 <br/>
	 *            如果路径以"<b>/xxx</b>"开头则从"<b>/xxx</b>"开始创建 <br/>
	 *            如果路径以"<b>xxx</b>"开头则从当前操作路径开始创建
	 * @return 成功返回true, 失败返回false
	 */
	public boolean makeDirs(String remotePath) {
		boolean result = false;
		if (dirValidation(remotePath)) {
			final String current = this.currentPath;

			String[] dirs;
			if (remotePath.startsWith("/")) {
				if (!remotePath.startsWith(current)) {
					throw new RuntimeException("需要创建的目录:" + remotePath
							+ ",不在基础目录:" + current);
				} else {
					dirs = StringUtil.split(
							remotePath.substring(current.length()), "/");
				}
			} else {
				dirs = StringUtil.split(remotePath, "/");
			}

			String path = current;
			if (path.endsWith("/")) {
				path = path.substring(0, path.length() - 1);
			}
			for (int i = 0; i < dirs.length; i++) {
				path += "/" + dirs[i];
				if (this.existFile(path)) {
					this.changeDir(path);
					continue;
				}
				if (dirValidation(path)) {
					try {
						channelSftp.mkdir(dirs[i]);
						this.changeDir(path);
						log.info("创建目录#" + path + "#");
					} catch (SftpException e) {
						throw new RuntimeException("创建目录'" + remotePath
								+ "'时发生错误：" + e.getMessage());
					}
				}

			}
			this.changeDir(current);
			return true;
		}
		return result;
	}

    /**
     * 删除远程服务器上的目录（仅可删除非空目录）
     * 
     * @param remotePath
     *            远程目录
     * @return 操作结果，成功为true，失败为false
     */
    public boolean removeDir(String remotePath) {
        boolean result = false;
        if (dirValidation(remotePath)) {
            String testPath = getOperationPath(remotePath);
            try {
                channelSftp.rmdir(testPath);
                result = true;
            }
            catch (SftpException e) {
                throw new RuntimeException("删除目录'" + remotePath + "'时发生错误：" + e.getMessage());
            }
        }
        return result;
    }

    /**
     * 内部方法，取得一个文件他所属的目录的路径
     * 
     * @param path
     *            文件路径
     * @return 判断结果，是返回ture，否则false
     */
    private String getFileDir(String path) {
        String result = "";
        if (path.lastIndexOf("/") >= 0) {
            result = path.substring(0, path.lastIndexOf("/"));
        }
        return result;
    }

    /**
     * 内部方法，取得一个文件的文件名
     * 
     * @param path
     *            文件路径
     * @return 判断结果，是返回ture，否则false
     */
    public String getFileName(String path) {
        String result = path;
        if (path.lastIndexOf("/") > -1) {
            result = path.substring(path.lastIndexOf("/") + 1, path.length());
        }
        return result;
    }

    /**
     * 判断文件是否存在
     * 
     * @param remoteFilePath
     *            文件路径
     * @return 文件存在，则返回true，否则返回false
     */
    public boolean existFile(String remoteFilePath) {
        boolean result = false;
        if (dirValidation(remoteFilePath)) {
            if (!this.isFilePath(remoteFilePath)) {
                throw new RuntimeException("这不是一个文件路径：" + remoteFilePath);
            }
            String pathDir = this.getFileDir(remoteFilePath);
            String realPathDir = this.getOperationPath(pathDir);
            String fileName = this.getFileName(remoteFilePath);
            
            
            try {
                Vector v = channelSftp.ls(realPathDir);
                if (null != v && v.size() > 0) {
                    for (int i = 0; i < v.size(); ++i) {
                        LsEntry e = (LsEntry) v.get(i);
                        if (e.getFilename().equals(fileName)) {
                            result = true;
                            break;
                        }
                    }
                }
            }
            catch (SftpException e1) {
                log.warn("文件不存在, remoteFilePath=" + remoteFilePath);
            }
        }
        return result;
    }

    /**
     * 判断文件是否存在
     * 
     * @param remoteFilePath
     *            文件路径
     * @return 文件存在，则返回true，否则返回false
     */
    public boolean existFileNew(String remoteFilePath) {
        log.info("[判断文件是否存在][开始][文件路径："+ remoteFilePath +"]");
        long start = System.currentTimeMillis();
        boolean result = false;
        if (dirValidation(remoteFilePath)) {
            if (!this.isFilePath(remoteFilePath)) {
                throw new RuntimeException("这不是一个文件路径：" + remoteFilePath);
            }
            String fileName = this.getFileName(remoteFilePath);
            try {
                Vector v = channelSftp.ls(remoteFilePath);
                log.info("查找文件个数：" + v.size());
                if (null != v && v.size() > 0) {
                    for (int i = 0; i < v.size(); ++i) {
                        LsEntry e = (LsEntry) v.get(i);
                        if (e.getFilename().equals(fileName)) {
                            result = true;
                        }
                    }
                }
            } catch (SftpException e1) {
                log.info("[判断文件是否存在][文件不存在][结束][耗时" + (System.currentTimeMillis() - start) + "]");
                return result;
            }
        }
        return result;
    }
    
    /**
     * 取得当前操作路径下的文件名列表(含文件夹)
     * 
     * @return 文件名列表
     * @throws SftpException 
     */
    public List < String > getFileList() throws SftpException {
        List < String > result = null;
        currentFiles = channelSftp.ls(currentPath);
        if (null != currentFiles && currentFiles.size() > 0) {
            result = new ArrayList < String > ();
            for (int i = 0; i < currentFiles.size(); ++i) {
            	String fileName = ((LsEntry) currentFiles.get(i)).getFilename();
            	if(!"..".equals(fileName) && !".".equals(fileName)){
            		result.add(((LsEntry) currentFiles.get(i)).getFilename());
            	}
            }
        }
        return result;
    }

	/**
	 * 递归取得当前操作路径下的文件、文件夹路径列表
	 * 
	 * @return 文件路径列表
	 */
	public List<String> getFilePathList() {
		String currTopDir = currentPath;
		try {
			return getFilePathList(currTopDir, null);
		} catch (Exception ex) {
			throw new RuntimeException(ex);
		} finally {
			changeDir(currTopDir);
		}
	}

	private List<String> getFilePathList(String baseDir, String subdir)
			throws Exception {
		String currListDir = baseDir;
		if (subdir != null && subdir.trim().length() > 0) {
			currListDir += "/" + subdir;
		}
		changeDir(currListDir);
		Vector currFiles = channelSftp.ls(currListDir);
		List<String> result = null;
		if (null != currFiles && currFiles.size() > 0) {
			result = new ArrayList<String>();
			for (int i = 0; i < currFiles.size(); ++i) {
				LsEntry lsEntry = (LsEntry) currFiles.get(i);
				String fileName = lsEntry.getFilename();
				if (!"..".equals(fileName) && !".".equals(fileName)) {
					String currSubFilePath;
					if (subdir != null && subdir.trim().length() > 0) {
						currSubFilePath = subdir + "/" + fileName;
					} else {
						currSubFilePath = fileName;
					}
					result.add(currSubFilePath);
					if (lsEntry.getAttrs() != null
							&& lsEntry.getAttrs().isDir()) {
						List<String> nextResult = getFilePathList(baseDir,
								currSubFilePath);
						if (nextResult != null && nextResult.size() > 0) {
							result.addAll(nextResult);
						}
					}
				}
			}
		}
		return result;
	}

	/**
	 * 从SFTP服务器下载整个目录至本地
	 * 
	 * @param remoteDirPath
	 *            远程文件路径
	 * @param localDirPath
	 *            本地文件路径
	 * @return boolean 下载是否成功
	 */
	public boolean downloadDir(String remoteDirPath, String localDirPath) {
		String currTopDir = currentPath;
		try {
			remoteDirPath = getFileOperationPath(remoteDirPath);
			return downloadDir(remoteDirPath, localDirPath, null);
		} catch (Exception ex) {
            log.error("", ex);
			return false;
		} finally {
			changeDir(currTopDir);
		}
	}

	private boolean downloadDir(String baseDir, String localDirPath,
			String subdir) throws Exception {
		String currListDir = baseDir;
		if (subdir != null && subdir.trim().length() > 0) {
			currListDir += "/" + subdir;
		}
		changeDir(currListDir);
		Vector currFiles = channelSftp.ls(currListDir);
		if (null != currFiles && currFiles.size() > 0) {
			for (int i = 0; i < currFiles.size(); ++i) {
				LsEntry lsEntry = (LsEntry) currFiles.get(i);
				String fileName = lsEntry.getFilename();
				if (!"..".equals(fileName) && !".".equals(fileName)) {
					String currSubFilePath;
					if (subdir != null && subdir.trim().length() > 0) {
						currSubFilePath = subdir + "/" + fileName;
					} else {
						currSubFilePath = fileName;
					}
					if (lsEntry.getAttrs() != null
							&& lsEntry.getAttrs().isDir()) {
						File localSubDir = new File(PathUtil.joinPath(
								localDirPath, currSubFilePath));
						if (!localSubDir.exists()) {
							localSubDir.mkdir();
						}
						boolean dlSubDirSuccFlag = downloadDir(baseDir, localDirPath, currSubFilePath);
						if(!dlSubDirSuccFlag){
							return dlSubDirSuccFlag;
						}
					} else {
						boolean dlSubFileSuccFlag = downloadFile(
								PathUtil.joinPath(baseDir, currSubFilePath),
								PathUtil.joinPath(localDirPath, currSubFilePath));
						if(!dlSubFileSuccFlag){
							return dlSubFileSuccFlag;
						}
					}
				}
			}
		}
		return true;
	}

    /**
     * 从SFTP服务器下载文件至本地
     * 
     * @param remoteFilePath
     *            远程文件路径
     * @param localFilePath
     *            本地文件路径
     * @return boolean
     */
    public boolean downloadFile(String remoteFilePath, String localFilePath) {
        if (dirValidation(remoteFilePath)) {
            if (!existFile(remoteFilePath)) {
                throw new RuntimeException("下载文件" + remoteFilePath + "时发生异常，远程文件并不存在");
            }
            OutputStream os = null;
            try {
                String realPath = getFileOperationPath(remoteFilePath);
                File file = new File(localFilePath);
                FileOutputStream fos = new FileOutputStream(file);
                // 从服务器下载文件到本地
                channelSftp.get(realPath, fos);
                this.getCurrentFileList();
                return true;
            }
            catch (Exception e) {
                log.error("下载文件：" + remoteFilePath + "时发生文件读写错误：", e);
                throw new RuntimeException("下载文件：" + remoteFilePath + "时发生文件读写错误：" + e.getMessage());
            }
//            catch (SftpException e) {
//                throw new RuntimeException("下载文件：" + remoteFilePath + "时发生Sftp错误：" + e.getMessage());
//            }
            finally {
                this.closeOutputStream(os);
            }
        }
        else {
            return false;
        }
    }

    /**
     * 删除服务器上的文件
     * 
     * @param remoteFilePath
     *            远程文件的完整路径
     * @return 操作结果(boolean型)
     */
    public boolean deleteFile(String remoteFilePath) {
        if (dirValidation(remoteFilePath)) {
            if (!existFile(remoteFilePath)) {
                throw new RuntimeException("删除文件" + remoteFilePath + "时发生异常，远程文件并不存在");
            }
            try {
                String realPath = getFileOperationPath(remoteFilePath);
                channelSftp.rm(realPath);
                return true;
            }
            catch (SftpException e) {
                throw new RuntimeException("删除文件：" + remoteFilePath + "时发生错误：" + e.getMessage());
            }
        }
        else {
            return false;
        }
    }

	/**
	 * 把本地整个目录上传至ftp服务器
	 * 
	 * @param remoteDirPath
	 *            ftp服务器路径
	 * @param localDirpath
	 *            本地路径
	 * @return 上传所有文件的字节数
	 */
	public long uploadDir(String remoteDirPath, String localDirpath) {
		long result = 0;
		String currTopDir = currentPath;
		try {
			File dirFile = new File(localDirpath);
			if (!dirFile.exists()) {
                log.error(localDirpath + " does not exist!");
				return -1;
			}
			File[] subFileA = dirFile.listFiles();
			if (subFileA != null && subFileA.length > 0) {
				for (File subFile : subFileA) {
					if ("..".equals(subFile.getName())
							|| ".".equals(subFile.getName())) {
						continue;
					}
					if (subFile.isDirectory()) {
						if (!this.existFile(PathUtil.joinPath(remoteDirPath,
								subFile.getName()))) {
							this.changeDir(remoteDirPath);
							this.makeDir(subFile.getName());
                            log.info("创建目录："
									+ PathUtil.joinPath(remoteDirPath,
											subFile.getName()));
						}
						long subDirLen = uploadDir(
								PathUtil.joinPath(remoteDirPath,
										subFile.getName()),
								PathUtil.joinPath(localDirpath,
										subFile.getName()));
						if (subDirLen < 0) {
							return subDirLen;
						}
						result += subDirLen;
					} else {
						long subFileLen = upload(
								PathUtil.joinPath(remoteDirPath,
										subFile.getName()),
								PathUtil.joinPath(localDirpath,
										subFile.getName()));
						if (subFileLen < 0) {
							return subFileLen;
						}
						result += subFileLen;
					}
				}
			}
		} catch (Exception ex) {
            log.error("", ex);
			return -1;
		} finally {
			if (!currentPath.equals(currTopDir)) {
				this.changeDir(currTopDir);
			}
		}
		return result;
	}

    /**
     * 上传文件
     * 
     * @return -1 文件不存在 -2 文件内容为空 >0 成功上传，返回文件的大小
     * @param remoteFilePath
     *            远程文件名
     * @param localFilepath
     *            本地文件名
     */
    @SuppressWarnings("finally")
    public long upload(String remoteFilePath, String localFilepath) {
        if (channelSftp == null || !channelSftp.isConnected()) {
            throw new RuntimeException("上传文件" + localFilepath + "时发生异常，channelSftp连接未创建");
        }
        InputStream is = null;
        long result = -1;
        try {
            File fileIn = new File(localFilepath);

            if (fileIn.exists()) {
                is = new FileInputStream(fileIn);
                result = fileIn.length();
                // 从本地上传到服务器
                channelSftp.put(is, remoteFilePath);
            }
            else {
                result = -1;
            }
        }
        catch (IOException e) {
            result = -1;
            throw new RuntimeException(e.getMessage() + ": 上传文件时发生错误！");
        }
        catch (SftpException e) {
            throw new RuntimeException(e.getMessage() + ": 上传文件时发生错误！");
        }
        finally {
            closeInputStream(is);

        }
        return result;
    }

    /**
     * 上传文件
     * 
     * @return -1 文件不存在 -2 文件内容为空 >0 成功上传，返回文件的大小
     * @param remoteFilePath
     *            远程文件名 这个remoteFilePath = 远程目录+文件名
     */
    @SuppressWarnings("finally")
    public long upload(String remoteFilePath, InputStream is) {
        if (channelSftp == null || !channelSftp.isConnected()) {
            throw new RuntimeException("上传文件时发生异常，channelSftp连接未创建");
        }
        long result = -1;
        try {
            // 从本地上传到服务器
            channelSftp.put(is, remoteFilePath);
        }
        catch (SftpException e) {
            throw new RuntimeException(e.getMessage() + ": 上传文件时发生错误！");
        }
        finally {
            closeInputStream(is);

        }
        return result;
    }

    
    /**
     * 上传文件
     * @param filename 文面名
     * @return 操作结果
     */
    public long upload(String filename) {
        String newname = "";
        if (filename.lastIndexOf("/") > -1) {
            newname = filename.substring(filename.lastIndexOf("/") + 1, filename.length());
        }
        else {
            newname = filename;
        }
        return upload(newname, filename);
    }

    /**
     * 关闭连接
     */
    public void closeConnection() {
    	if (channelExec != null) {
            if (channelExec.isConnected()) {
            	channelExec.disconnect();
            }
        }
    	
        if (channelSftp != null) {
            if (channelSftp.isConnected()) {
                channelSftp.disconnect();
                session.disconnect();
            }
        }
    }

    /**
     * 下载文件，并写入HttpServletResponse（浏览器方式）
     * @param remoteFilePath 远程文件路径
     * @param response HttpServletResponse
     * @param fileName 通过浏览器，下载时看到的文件名
     * @return 操作结果，成功返回true，失败返回false
     */
    public boolean downloadFile(String remoteFilePath, HttpServletResponse response, String fileName) {
        if (dirValidation(remoteFilePath)) {
            if (!existFile(remoteFilePath)) {
                throw new RuntimeException("下载文件" + remoteFilePath + "时发生异常，远程文件并不存在");
            }
            OutputStream os = null;
            //String fileName = remoteFilePath.substring(remoteFilePath.lastIndexOf(File.separator) + 1);
            try {
                response.setHeader("Content-disposition", "attachment;filename="
                        + new String(fileName.getBytes("GBK"), "ISO8859-1"));
                os = response.getOutputStream();
                // 从服务器下载到本地
                channelSftp.get(remoteFilePath, os);
                return true;
            }
            catch (IOException e) {
                throw new RuntimeException("下载文件：" + remoteFilePath + "时发生文件读写错误：" + e.getMessage());
            }
            catch (SftpException e) {
                throw new RuntimeException("下载文件：" + remoteFilePath + "时发生Sftp错误：" + e.getMessage());
            }
            finally {
                this.closeOutputStream(os);
            }
        }
        else {
            return false;
        }
    }
    
    /**
     * 执行linux命令
     * 
     * @param cmd
     * @throws Exception 
     */
    public void execCommand(String cmd) throws Exception{
    	BufferedReader reader = null;  
    	
        try {  
           if(!"".equals(StringUtil.getString(cmd))) {  
        	   channelExec = (ChannelExec) session.openChannel("exec");  
           	
               channelExec.setCommand(cmd);  
               channelExec.setInputStream(null);  
               channelExec.setErrStream(System.err);
               channelExec.connect();  
 
               InputStream inputStream = channelExec.getInputStream();  
               reader = new BufferedReader(new InputStreamReader(inputStream));
               String buf = null;  
               while ((buf = reader.readLine()) != null) {  
                   System.out.println(buf);  
               }  
            }  
        } catch (Exception e) {  
        	throw new RuntimeException("执行命令：" + cmd + "时发生错误：" + e.getMessage());
        } finally {
            if(reader!=null){
                reader.close();
            }
            channelExec.disconnect();
        }  
    }

    /**
     * 从SFTP服务器获取文件的输出流
     * 
     * @param remoteFilePath
     *            远程文件路径
     * 
     * @return inputStream
     */
    public InputStream getInputStream(String remoteFilePath){
    	InputStream is = null;
    	if (dirValidation(remoteFilePath)) {
            if (!existFile(remoteFilePath)) {
                throw new RuntimeException("下载文件" + remoteFilePath + "时发生异常，远程文件并不存在");
            }
            try {
                String realPath = getFileOperationPath(remoteFilePath);
                is = channelSftp.get(realPath);
            }
            catch (Exception e) {
                log.error("下载文件：" + remoteFilePath + "时发生文件读写错误：", e);
                throw new RuntimeException("下载文件：" + remoteFilePath + "时发生文件读写错误：" + e.getMessage());
            }
        }
    	return is;
    }
    
}
